package me.feng.actors

import java.nio.CharBuffer
import com.lambdaworks.jacks.JacksMapper
import akka.actor.Actor
import me.feng.entity.Event
import me.feng.entity.Message
import me.feng.entity.User
import me.feng.entity.EventType
import me.feng.entity.Letter
import me.feng.messageinbound.MainChart
import scala.collection.mutable.Map
import me.feng.entity.LetterType
import me.feng.entity.MessageType
import me.feng.util.CacheUtil
import me.feng.service.FriendsService
import scala.collection.JavaConversions._

class UserActor(u: User) extends Actor {

  private val chatMap: Map[String, MainChart] = Map[String, MainChart]()

  private val msgCache: Map[String, List[Message[Letter]]] = Map[String, List[Message[Letter]]]()

  def receive = {

    case chat: MainChart => {

      chat.setUser(u)
      chatMap += (chat.getCid -> chat)

      if (!chat.getCid().equals("0")) {
        Thread.sleep(1000)
        val msgList = if (msgCache.contains(chat.getCid())) msgCache(chat.getCid()) else List()
        if (msgList.size > 0) {
          msgList.foreach(msg => {
            chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
          })
          msgCache.remove(chat.getCid)
        }
      }

      chatMap.foreach(p => {
        println("ChatMap: " + p._1 + " -> " + p._2.getUser.id)
      })
    }

    case msg: Message[Letter] => {

      chatMap.foreach(p => {
        println("ChatMap: " + p._1 + " -> " + p._2.getUser.id)
      })

      val uid = msg.result.kind match {
        case LetterType.MAIN => "0"
        case LetterType.USER => {
          if (msg.result.from.id.equals(u.id)) msg.result.cid else msg.result.from.id
        }
      }

      if (chatMap.contains(uid)) {
        val chat = chatMap(uid)
        if (chat != null && chat.open)
          chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
      } else {
        if (msgCache.contains(uid)) {
          msgCache(uid) :+= msg
        } else {
          msgCache += (uid -> List(msg))
        }
        val e = new Event(msg.result.from, msg.result.cid, EventType.NEW_SESSION)
        sender ! e
      }
    }

    case e: Event => {
      val msg = new Message(MessageType.EVENT, e)
      e.event match {
        case EventType.CLOSE => {
          chatMap.values.foreach(chat => {
            if (chat != null && chat.open)
              chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
          })
        }

        case EventType.LOGIN => {
          val chat = chatMap("0")
          if (chat != null && chat.open)
            chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
        }

        case EventType.EXIT_SESSION => {
          chatMap -= e.eid
        }

        case _ => {
          val chat = chatMap("0")
          if (chat != null && chat.open)
            chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
        }
      }

    }

    case "REFRESH_ONLINE_USERS" => {
      val chat = chatMap("0")
      if (chat != null && chat.open) {
        CacheUtil.getAllOlUser.foreach(uid => {
          val event = new Event(CacheUtil.getOlUser(uid), "0", EventType.REFRESH_ONLINE_USERS)
          val msg = new Message(MessageType.EVENT, event)
          chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
        })

        val friends = new FriendsService().getMyFriends(u.id).toList
        friends.foreach(f => {
          f.online = CacheUtil.getOlUser(f.id) != null
          val event = new Event(f, "0", EventType.REFRESH_FRIENDS)
          val msg = new Message(MessageType.EVENT, event)
          chat.getWsOutbound().writeTextMessage(CharBuffer.wrap(JacksMapper.writeValueAsString(msg)))
        })
      }
    }
  }
}